package xyz.kongbai121.drawingbed.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import xyz.kongbai121.drawingbed.constant.DrawingBedConstant;
import xyz.kongbai121.drawingbed.utils.Query;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import xyz.kongbai121.drawingbed.dao.ImageDao;
import xyz.kongbai121.drawingbed.entity.ImageEntity;
import xyz.kongbai121.drawingbed.service.ImageService;
import xyz.kongbai121.drawingbed.utils.PageUtils;


@Slf4j
@Service("imageService")
public class ImageServiceImpl extends ServiceImpl<ImageDao, ImageEntity> implements ImageService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final String IMAGE_KEY_PREFIX = "image:info:";

    private static final String IMAGES_KEY_PREFIX = "image:list:";

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String name = (String) params.get("name");
        String month = (String) params.get("month");
        String curPage = (String) params.get("page");
        String limit = (String) params.get("limit");

        //如果只有分页参数
        if (StringUtils.isBlank(name) && StringUtils.isBlank(month)){
            synchronized (this) {
                if (!redisTemplate.hasKey(IMAGES_KEY_PREFIX + curPage + ":" + limit)) {
                    IPage<ImageEntity> page = this.page(
                            new Query<ImageEntity>().getPage(params),
                            new QueryWrapper<ImageEntity>().orderByDesc("time")
                    );
                    PageUtils pageUtils = new PageUtils(page);
                    redisTemplate.opsForValue().set(IMAGES_KEY_PREFIX + curPage + ":" + limit, JSON.toJSONString(pageUtils), 30, TimeUnit.MINUTES);
                }
            }
            String json = redisTemplate.opsForValue().get(IMAGES_KEY_PREFIX + curPage + ":" + limit);
            PageUtils pageUtils = JSON.parseObject(json, new TypeReference<PageUtils>() {
            });
            return pageUtils;
        }

        // TODO 缓存设计
        QueryWrapper<ImageEntity> wrapper = new QueryWrapper<>();
        if (!StringUtils.isBlank(name)) {
            wrapper.like("name", name);
        }
        if (!StringUtils.isBlank(month)){
            wrapper.apply("date_format(time,'%Y-%m') = {0}", month);
        }
        IPage<ImageEntity> page = this.page(
                new Query<ImageEntity>().getPage(params),
                wrapper.orderByDesc("time")
        );

        return new PageUtils(page);
    }

    @Override
    @Transactional
    public void delele(Long id) {
        ImageEntity entity = this.getById(id);
        // 将文件添加到待删除队列
        String fileName = entity.getSrc().substring(entity.getSrc().lastIndexOf("/") + 1);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
        redisTemplate.opsForList().rightPush(DrawingBedConstant.OVER_IMAGES, simpleDateFormat.format(entity.getTime()) + "/" + fileName);
        this.removeById(id);
        log.info("图片删除:{}",entity);
        //删除缓存
        redisTemplate.delete(IMAGE_KEY_PREFIX+id);
        Set<String> keys = redisTemplate.keys(IMAGES_KEY_PREFIX + "*");
        if (keys != null){
            redisTemplate.delete(keys);
        }
    }


    @Override
    public ImageEntity getById(Serializable id) {
        ImageEntity entity = null;
        synchronized (this) {
            if (!redisTemplate.hasKey(IMAGE_KEY_PREFIX + id)) {
                entity = super.getById(id);
                redisTemplate.opsForValue().set(IMAGE_KEY_PREFIX + id, JSON.toJSONString(entity),30, TimeUnit.MINUTES);
            }
        }
        String json = redisTemplate.opsForValue().get(IMAGE_KEY_PREFIX + id);
        entity = JSON.parseObject(json, new TypeReference<ImageEntity>(){});
        return entity;
    }

    @Override
    public boolean save(ImageEntity entity) {
        boolean save = super.save(entity);
        Set<String> keys = redisTemplate.keys(IMAGES_KEY_PREFIX + "*");
        if (keys != null){
            redisTemplate.delete(keys);
        }
        log.info("图片新增:{}",entity);
        return save;
    }
}